package org.jsola.hr.provider;

import org.jsola.admin.vo.HeaderFieldsVO;
import org.jsola.contract.constant.AccountType;
import org.jsola.contract.dto.*;
import org.jsola.contract.entity.*;
import org.jsola.contract.query.AppendixQuery;
import org.jsola.contract.query.ContractGroupQuery;
import org.jsola.contract.query.ContractQuery;
import org.jsola.contract.query.SealQuery;
import org.jsola.contract.vo.*;
import org.jsola.core.Page;
import org.jsola.core.Result;
import org.jsola.file.entity.FileVersionDO;
import org.jsola.hr.dto.HrContractDownloadDTO;
import org.jsola.hr.dto.HrPublishSignDTO;
import org.jsola.hr.dto.TemplateVariableUpdateDTO;
import org.jsola.hr.dto.contract.AddSealDTO;
import org.jsola.hr.dto.contract.UpdateSealDTO;
import org.jsola.hr.dto.contract.VerifyEnterpriseDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.query.HrContractExportQuery;
import org.jsola.hr.query.HrContractQuery;
import org.jsola.hr.vo.FailCategoryVO;
import org.jsola.hr.vo.HrContractListVO;
import org.jsola.hr.vo.HrVariableListVO;
import org.jsola.user.core.TokenUser;

import java.util.List;
import java.util.Map;

/**
 * @author JanusMix
 */
public interface IContractProviderService {

    /**
     * 保存印章
     *
     * @param addSealDTO 保存对象
     * @param tokenUser  当前登录用户
     * @return vo
     */
    SealVO saveSeal(AddSealDTO addSealDTO, TokenUser tokenUser);

    /**
     * 修改印章
     *
     * @param sealUpdateDTO 印章更新对象
     * @param tokenUser     当前登录用户
     * @return 更新行数
     */
    int updateSeal(UpdateSealDTO sealUpdateDTO, TokenUser tokenUser);

    /**
     * 根据用工单位id查询印章
     *
     * @param companyId 用工单位id
     * @param siteId    站点id
     * @return vo
     */
    SealDO selectSealByCompanyId(String companyId, String siteId);

    /**
     * 根据id查询印章
     *
     * @param sealId 印章id
     * @param siteId 站点id
     * @return vo
     */
    SealVO selectSealById(Long sealId, String siteId);

    /**
     * 根据id查询印章
     *
     * @param sealIds 印章id
     * @param siteId  站点id
     * @return vo
     */
    List<SealDO> selectSealByIds(List<Long> sealIds, String siteId);

    /**
     * 查询印章列表
     *
     * @param sealQuery 查询对象
     * @param siteId    站点id
     * @return 列表对象
     */
    List<SealListVO> sealSealList(SealQuery sealQuery, String siteId);

    /**
     * 企业授权
     *
     * @param verifyEnterpriseDTO 企业认证对象
     * @param tokenUser           当前登录用户
     */
    void verifyEnterprise(VerifyEnterpriseDTO verifyEnterpriseDTO, TokenUser tokenUser);

    /**
     * 员工实名认证
     *
     * @param userId     用户id
     * @param name       用户名
     * @param phone      手机号
     * @param idNo       身份证号
     * @param personArea id类型
     * @param tokenUser  当前登录用户
     */
    void verifyEmployee(String userId, String name, String phone, String idNo, String personArea, TokenUser tokenUser);

    /**
     * 查询所有变量
     *
     * @return list
     */
    List<VariableListVO> selectAllVariable();

    /**
     * 获取模板关联的变量
     *
     * @param templateId 模板id
     * @param siteId     站点id
     * @return list
     */
    List<TemplateVariableListVO> selectVariableByTemplateId(Long templateId, String siteId);

    /**
     * 查询用户合同列表
     *
     * @param tokenUser 当前登录用户
     * @return 签署方list
     */
    List<PartySignListVO> selectUserContractList(TokenUser tokenUser);

    /**
     * 根据id查询合同类型
     *
     * @param categoryId 类型id
     * @param siteId     站点id
     * @return 类型vo
     */
    CategoryVO selectCategoryById(Long categoryId, String siteId);

    /**
     * 根据id查询合同类型
     *
     * @param categoryIds 类型id
     * @return 类型vo
     */
    List<CategoryDO> selectCategoryByIds(List<Long> categoryIds);


    /**
     * 添加合同类型（此方法会在该合同类型里面自动添加一个空的模板，模板名和类型名一样）
     *
     * @param categoryAddDTO 合同类型数据
     * @param tokenUser      当前用户
     * @return 合同类型
     */
    CategoryVO saveCategory(CategoryAddDTO categoryAddDTO, TokenUser tokenUser);

    /**
     * 获取某业务的所有类型
     *
     * @param subjectId 分组id
     * @param siteId    站点id
     * @return 类型DO列表
     */
    List<CategoryDO> listBySubjectId(String subjectId, String siteId);

    /**
     * 获取模板变量map列表
     *
     * @param templateId 模板id
     * @param siteId     站点id
     * @return list
     */
    List<Map<String, Object>> getVariableMapList(Long templateId, String siteId);

    /**
     * 根据id查询模板
     *
     * @param templateId 模板id
     * @param siteId     站点id
     * @return DO
     */
    TemplateDO getTemplateById(Long templateId, String siteId);

    /**
     * 更新员工账号的手机号
     *
     * @param oldPhone  旧手机号
     * @param memberId  用户id
     * @param newPhone  新手机号
     * @param tokenUser 当前用户
     */
    void updateUserPhone(String oldPhone, String memberId, String newPhone, TokenUser tokenUser);

    /**
     * 合同概况数量统计
     *
     * @param contractType 合同类型
     * @param subjectId    业务ID
     * @param tokenUser    当前用户
     */
    ContractCountVO getContractCount(Integer contractType, String subjectId, TokenUser tokenUser);

    /**
     * 合同概况数量统计(业务id可以传多个)
     *
     * @param contractType 合同类型
     * @param subjectIds   业务IDs
     * @param tokenUser    当前用户
     * @return 合同统计信息
     */
    ContractCountVO getContractCount(Integer contractType, List<String> subjectIds, TokenUser tokenUser);

    /**
     * 查询合同文件,并进行打包
     *
     * @param hrContractDownloadDTO 查询合同的参数
     * @param tokenUser             当前用户
     * @return 合同下载信息
     */
    FileVersionDO downloadContract(HrContractDownloadDTO hrContractDownloadDTO, TokenUser tokenUser);

    /**
     * 删除合同及关联信息
     *
     * @param contractId 合同id
     * @param tokenUser  当前用户
     */
    void deleteContractAndRelationById(Long contractId, TokenUser tokenUser);

    /**
     * 租户是否开通电子合同增值服务
     *
     * @param tokenUser 当前登录用户
     * @return true or false
     */
    boolean isSiteContractEnable(TokenUser tokenUser);


    /**
     * 查看某个员工的所有签署记录中时间最新的那条签署记录
     *
     * @param userId    员工用户Id
     * @param subjectId 公司Id
     * @param empId     员工id
     * @param tokenUser 当前登录用户
     * @return 签署记录
     */
    ContractDO selectAllSignedRecording(String userId, String subjectId, String empId, TokenUser tokenUser);

    /**
     * 查看某个员工的所有签署记录中签署时间最晚的的那条签署记录
     *
     * @param companyId 公司Id
     * @param empId     员工id
     * @param tokenUser 当前登录用户
     * @return 签署记录
     */
    ContractDO selectAllSignedRecordingByCompanyIdAndEmpId(String companyId, String empId, TokenUser tokenUser);

    /**
     * 查询合同列表
     *
     * @param hrContractExportQuery 查询参数
     * @param tokenUser             当前用户
     * @return 合同列表
     */
    String selectExportContractList(HrContractExportQuery hrContractExportQuery, TokenUser tokenUser);

    /**
     * 分页查询用工单位排名
     *
     * @param contractQuery 查询参数
     * @param tokenUser     当前用户
     * @return 用工单位排名
     */
    Page<ContractStatisticsEmpUnitsVO> selectComForRankCount(ContractQuery contractQuery, TokenUser tokenUser);

    /**
     * 分页查询用工单位排名(会根据业务ids查询)
     *
     * @param contractQuery 查询参数
     * @param tokenUser     当前用户
     * @return 用工单位排名
     */
    Page<ContractStatisticsEmpUnitsVO> selectComForRankCountPost(ContractQuery contractQuery, TokenUser tokenUser);


    /**
     * 获取租户合同签署剩余量
     *
     * @param siteId 租户id
     * @return 数量，-1为不限
     */
    int getSiteContractLeftCount(String siteId);

    /**
     * 分页查询合同
     *
     * @param contractQuery 查询参数
     * @param tokenUser     当前用户
     * @return 合同分页对象
     */
    Page<ContractListVO> selectPageContract(ContractQuery contractQuery, TokenUser tokenUser);

    /**
     * 分页查询合同(业务id可以传多个)
     *
     * @param contractQuery 查询参数
     * @param tokenUser     当前用户
     * @return 合同分页对象
     */
    Page<HrContractListVO> selectPageBySubjectIds(ContractQuery contractQuery, TokenUser tokenUser);


    /**
     * 发起模板单方签署
     *
     * @param hrPublishSignDTO dto
     * @param tokenUser        当前登录用户
     * @return 合同信息
     */
    List<ContractVO> publishTemplateSign(HrPublishSignDTO hrPublishSignDTO, TokenUser tokenUser);


    /**
     * 分页查询合同
     *
     * @param hrContractQuery 查询条件
     * @param siteId          所属站点id
     * @return 合同列表信息
     */
    Page<HrContractListVO> selectContractPage(HrContractQuery hrContractQuery, String siteId);


    /**
     * 查询合同文件
     *
     * @param appendixQuery 查询条件
     * @param siteId        所属站点id
     * @return 合同文件列表信息
     */
    List<AppendixListVO> selectAppendix(AppendixQuery appendixQuery, String siteId);


    /**
     * 签署合同发送验证码
     *
     * @param tokenUser 当前登录用户
     * @return 发送验证码的结果
     */
    Result<Boolean> sendContractCode(TokenUser tokenUser);

    /**
     * 查询所有未到期的合同,不包含合同富文本内容
     *
     * @return 合同列表
     */
    List<ContractDO> listAllNoExpireContract();

    /**
     * 根据id查询合同,不包含合同富文本内容
     *
     * @param id 合同id
     * @return 合同
     */
    ContractDO selectById(Long id);

    /**
     * 查询业务所属的所有印章
     *
     * @param subjectId 业务id
     * @param siteId    所属站点id
     * @return 印章列表信息
     */
    List<SealDO> selectBySubjectId(String subjectId, String siteId);

    /**
     * 下发印章到公司
     *
     * @param issuedSealAddDTO 印章
     * @param tokenUser        登录用户
     * @return 印章
     */
    List<SealVO> saveIssuedSeal(IssuedSealAddDTO issuedSealAddDTO, TokenUser tokenUser);


    /**
     * 下发合同模版到公司
     *
     * @param issuedCategoryAddDTO 合同模版
     * @param tokenUser            登录用户
     * @return 合同类型
     */
    List<FailCategoryVO> saveIssuedCategory(IssuedCategoryAddDTO issuedCategoryAddDTO, TokenUser tokenUser);


    /**
     * 合同模板关联默认字段转化为必填字段
     *
     * @param tokenUser 登录用户
     */
    void issuedDefaultVariable(TokenUser tokenUser);

    /**
     * 修复合同变量
     */
    void repairTemplateVariable();

    /**
     * 查询模板变量 个人信息拉取花名册
     *
     * @param companyId 公司Id
     * @param fieldName 字段名称 模糊查询
     * @param tokenUser 登录用户
     * @return 模板变量列表信息
     */
    List<HrVariableListVO> selectVariableNotPersonal(String companyId, String fieldName, TokenUser tokenUser);

    /**
     * 修改合同模板
     *
     * @param templateUpdateDTO 修改合同模板DTO
     * @param tokenUser         当前用户
     * @return 更新数量
     */
    int updateTemplate(TemplateUpdateDTO templateUpdateDTO, TokenUser tokenUser);

    /**
     * 批量编辑、新增、删除合同模板关联变量
     *
     * @param templateVariableUpdateDTO 要操作的合同模板关联变量
     * @param tokenUser                 登录用户
     */
    void updateTemplateVariable(TemplateVariableUpdateDTO templateVariableUpdateDTO, TokenUser tokenUser);

    /**
     * 根据合同pdf转图片放到合同文件中
     *
     * @param contractId 合同id
     * @param tokenUser  当前用户
     * @return 1
     */
    Integer setJpgToAppendix(Long contractId, TokenUser tokenUser);

    /**
     * 根据用工单位id查询该用工单位的所有合同模板
     *
     * @param companyId 用工单位id
     * @param siteId    租户id
     * @return 模板list
     */
    List<TemplateDO> selectByCompanyId(String companyId, String siteId);

    /**
     * 修改合同模板
     *
     * @param templateDO 合同信息
     * @param tokenUser  当前用户
     * @return 修改条数
     */
    Integer updataTemplateDO(TemplateDO templateDO, TokenUser tokenUser);

    /**
     * 根据合同id查询员工信息 已删除员工以能查到
     *
     * @param contractId 合同id
     * @return 员工信息
     */
    EmpInfoDO selectEmpInfoByContractId(Long contractId);


    /**
     * 根据合同id查询员工信息
     *
     * @param contractIds 合同ids
     * @return 员工信息
     */
    List<EmpInfoDO> selectEmpInfoByContractIds(List<Long> contractIds);


    /**
     * 查询电子合同签署记录表头字段
     *
     * @param companyId 用工单位Id
     * @param tokenUser 当前用户
     * @return List
     */
    HeaderFieldsVO getSignedRecordHead(String companyId, TokenUser tokenUser);

    /**
     * 查询管理后台电子合同签署记录表头字段
     *
     * @param companyId 用工单位Id
     * @param tokenUser 当前用户
     * @return List
     */
    HeaderFieldsVO getAdminSignedRecordHead(String companyId, TokenUser tokenUser);

    /**
     * 修改合同
     *
     * @param contractUpdateDTO 修改合同DTO
     * @param tokenUser         当前用户
     * @return 更新数量
     */
    int updateContract(ContractUpdateDTO contractUpdateDTO, TokenUser tokenUser);

    /**
     * 查询指定账户的合同名以指定字段开头的数量
     *
     * @param name            名称
     * @param partyBAccountId B方Id
     * @param notContractId   排除Id 为空查所有
     * @return 数量
     */
    int selectCountByNameStart(String name, String partyBAccountId, Long notContractId);

    /**
     * 发起模板签署
     *
     * @param publishSignDTO dto
     * @param tokenUser      当前登录用户
     * @return 合同信息
     */
    List<ContractVO> publishTemplateSign(PublishSignDTO publishSignDTO, TokenUser tokenUser);

    /**
     * 发起模板签署(异步，直接返回success)
     *
     * @param publishSignDTO dto
     * @param tokenUser      当前登录用户
     * @return 合同信息
     */
    String publishTemplateSignAsync(PublishSignDTO publishSignDTO, TokenUser tokenUser);


    /**
     * 批量删除合同
     *
     * @param tokenUser   当前用户
     * @param contractIds 合同id
     * @return 删除数量
     */
    int deleteContractByIds(TokenUser tokenUser, Long... contractIds);

    /**
     * 同步花名册电子合同
     */
    public void saveEmpContract(ContractVO contractVO, TokenUser tokenUser);

    /**
     * 修改合同文件的文件名称
     *
     * @param contractId   合同Id
     * @param contractName 合同名称
     * @param tokenUser    登录用户
     */
    void updateFileName(Long contractId, String contractName, TokenUser tokenUser);

    /**
     * 查询合同类型分组 同时同步默认分组
     *
     * @param contractGroupQuery 查询条件
     * @param tokenUser          所属站点id
     * @return 合同类型分组列表信息
     */
    List<ContractGroupListVO> selectAndSynchronizeContractGroup(ContractGroupQuery contractGroupQuery, TokenUser tokenUser);

    /**
     * 修改合同类型
     *
     * @param categoryUpdateDTO 修改合同类型DTO
     * @param tokenUser         当前用户
     * @return 更新数量
     */
    int updateCategory(CategoryUpdateDTO categoryUpdateDTO, TokenUser tokenUser);

    String demoAsync(PublishSignDTO publishSignDTO, TokenUser tokenUser);

    /**
     * 确认签署合同,单个签署
     *
     * @param contractId 合同id
     * @param companyId  公司id
     * @param tokenUser  当前用户
     */
    void enterpriseSignAgain(Long contractId, String companyId, TokenUser tokenUser);

    /**
     * 获取合同的签署方账户信息
     *
     * @param contractId 合同id
     * @param siteId     站点
     * @return 账户信息
     */
    List<PartySignAccountVO> findPartySignAccount(Long contractId, String siteId);

    /**
     * 根据合同id集合查询合同文件
     *
     * @param contractIdList 合同id集合
     * @param siteId         站点id
     * @return 合同文件
     */
    List<AppendixDO> appendixListByContractIds(List<Long> contractIdList, String siteId);

    /**
     * 根据成员id查询合同账户
     *
     * @param type     账户类型
     * @param memberId 成员id
     * @return 合同账户
     */
    AccountDO findAccount(AccountType type, String memberId);

    /**
     * 查询印章位置
     *
     * @param contractId 合同id
     * @param tokenUser  登录用户
     * @return SealPositionDO
     */
    List<SealPositionDO> selectByContractId(Long contractId, TokenUser tokenUser);

    /**
     * 获取合同签署链接
     *
     * @param contractId 合同id
     * @param type       1:个人 2：公司
     */
    String getUrl(Long contractId, Integer type, TokenUser tokenUser);

    /**
     * 个人签署
     */
    void personSign(Long contractId, byte[] stream, Boolean showDiffSite, TokenUser tokenUser);

    /**
     * 公司签署
     * @param companyId hr_company_contract_quota认证企业id
     */
    void companySign(Long contractId, String companyId, byte[] bytes, boolean showDiffSite, TokenUser tokenUser);

    /**
     * 根据合同编号查询合同
     */
    ContractDO selectByContractNo(String contractNo);

    List<SealListVO> selectSeal( SealQuery sealQuery, String siteId);

    ///**
    // * 撤销合同
    // *
    // * @param contractId 合同id
    // * @param tokenUser  登录人
    // */
    //Integer cancel(Long contractId, TokenUser tokenUser);
}
